<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../lib/index.js"></script>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        canvas{
            margin: 50px auto 0;
            display: block;
            background: yellow;
        }
    </style>
</head>
<body>
<canvas id="canvas" width="400" height="400"></canvas>
</body>
<script>
    let ctx = document.getElementById('canvas');
    // 获取webgl上下文
    let gl = ctx.getContext('webgl')

    // 顶点着色器
    let VERTEX_SHADER_SOURCE = `
        attribute vec4 aPosition;
        attribute float aPointSize;
        attribute vec4 aTex;
        // 使用varying变量 将顶点坐标数据 传递给片元着色器
        varying vec2 vTex; // 如何把aTex值 传递给VTex
        void main(){
            gl_Position = aPosition;
            gl_PointSize = aPointSize;
            vTex = vec2(aTex.x, aTex.y);
        }
    `;
    // 片元着色器
    const FRAGMENT_SHADER_SOURCE = `
        precision lowp float;
        // 如何使用纹理图片， 在着色器中创建smpler2D变量
        uniform sampler2D uSampler;
        // 多重纹理 需要多个变量 接收纹理数据
        uniform sampler2D uSampler1;
         // 也可以使用 samplerCube 接收立方体纹理
         // uniform samplerCube uSampler;

        // 然后再片元着色器中 声明同样的vTex,然后再 纹理中使用
        varying vec2 vTex;
        void main(){
            // texture2D 返回值是vec4类型
            vec4 c1 = texture2D(uSampler, vTex);
            vec4 c2 = texture2D(uSampler1, vTex);
            // 通过相乘的方式 让c1 c2 共同作用在FragColor上
            gl_FragColor = c1 * c2;
        }
    `;
    let program = initShader(gl, VERTEX_SHADER_SOURCE, FRAGMENT_SHADER_SOURCE)
    // 获取 attribute变量，必须在initShader之后
    let aPosition = gl.getAttribLocation(program, 'aPosition')
    let aTex = gl.getAttribLocation(program, 'aTex')
    let uSampler = gl.getUniformLocation(program, 'uSampler')
    let uSampler1 = gl.getUniformLocation(program, 'uSampler1')

    // 创建一组顶点数据   Float32Array类型化数组，用这个数组，既可以知道里面是数据类型
    let points = new Float32Array([
       -0.5,  0.5, 0.0, 1.0,
       -0.5, -0.5, 0.0, 0.0,
        0.5,  0.5, 1.0, 1.0,
        0.5, -0.5, 1.0, 0.0,
    ])
    // 创建缓冲区
    let buffer = gl.createBuffer();
    // 将缓冲区对象 绑定到 webgl上
    gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
    // 将顶点数据 写入 缓冲区对象
    gl.bufferData(gl.ARRAY_BUFFER, points, gl.STATIC_DRAW);
    // 相邻数据的字节数 0 字节数如何获取  几个数据能表示一个信息，就乘以几
    let BYTES = points.BYTES_PER_ELEMENT;
    // 偏移量 每一次数据使用两个，都是连续的，所以不需要偏移量
    gl.vertexAttribPointer(aPosition, 2, gl.FLOAT, false, BYTES*4, 0 )
    // 激活attribute变量  gl.disableVertexAttribArray(aPosition); 使⽤此⽅法禁⽤
    gl.enableVertexAttribArray(aPosition);

    gl.vertexAttribPointer(aTex, 2, gl.FLOAT, false, BYTES*4, BYTES*2 )
    gl.enableVertexAttribArray(aTex);


    function getImage(url, location, index){
        // 通过 Promise 优化异步操作
        return new Promise( resolve => {
            /*
转换图片坐标
 转换之后的图片坐标叫做纹理坐标。 纹理坐标 也叫做 st坐标

*/
            const img = new Image();
            img.onload = function () {
                // 创建纹理对象 用来存储纹理图形数据  可以通过gl。deleteTexture(texture) 删除texture纹理对象
                const texture = gl.createTexture();
                // 反转图片 ，让图片坐标和webgl坐标相同， 图片坐标原点在左上角 而webgl原点在左下角
                gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
                // 开启一个纹理单元   纹理单元管理 纹理对象。每个纹理单元管理一张纹理图像
                gl.activeTexture(gl[`TEXTURE${index}`])
                // 绑定纹理对象
                gl.bindTexture(gl.TEXTURE_2D, texture);
                // 图像缩放 纹理如何处理
                // 处理放大   gl.NEAREST 使用最近像素颜色值   gl.LINEAR 使用四周的像素颜色值的平均值
                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
                // 处理缩小
                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
                // 横向 纵向 平铺的处理   CLAMP_TO_EDGE边缘延伸
                // 横向
                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
                // 纵向
                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)

                // 纹理对象配置到纹理单元  type level internalformat图像的内部格式，png就是rgba，fromat纹理的内部格式，必须和internalformat相同
                //  dataType纹理数据的数据类型 image对象图片
                // gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, img )
                gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img )

                /*
                uSampler uniform新的赋值方式
                    usampler  uniform变量名,
                    0 当前开启的纹理单元室那个  编号是0的
                */
                // uniform1i  数组1+i 结尾，表示接收的是整型
                // uniform1f  数组1+f 结尾，表示接收的是浮点型
                gl.uniform1i(location, index);

                resolve()
            }
            // img.src = '../assets/raone.png'
            img.src = url
        } )

    }

    Promise.all([getImage('../assets/ytydLogo_02.jpg', uSampler1, 1),getImage('../assets/posx_01.jpg', uSampler, 0)]).then(()=>{
        // 绘制图形的时候 gl_PointSize 不生效
        gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); // 绘制多边形 梯形
    })


</script>
</html>
